package edu.uw.cs.cse461.sp12.snet;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import edu.uw.cs.cse461.sp12.DB461.DB461.DB461Exception;
import edu.uw.cs.cse461.sp12.OS.DDNSFullName;
import edu.uw.cs.cse461.sp12.OS.SNetControl;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;

public class SNetUpdate extends Activity {
	private static final String TAG = "SNetUpdate";

	private Spinner spinner;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.update);
        
    	spinner = (Spinner) findViewById(R.id.community_spinner);
    	
		updateActivityView();
        
        Button befriendButton = (Button) findViewById(R.id.befriend_button);
        befriendButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				befriend();
			}
        });
        Button unfriendButton = (Button) findViewById(R.id.unfriend_button);
        unfriendButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				unfriend();
			}
        });
        Button contactButton = (Button) findViewById(R.id.contact_button);
        contactButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				contact();
			}
        });
        Button fixDBButton = (Button) findViewById(R.id.fix_db_button);
        fixDBButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				fixDB();
			}
        });
        Button dumpDBButton = (Button) findViewById(R.id.dump_db_button);
        dumpDBButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dumpDB();
			}
        });
    }
    
	private void befriend() {
		try {
			SNetControl.befriend(getSelectedHost());
		} catch (DB461Exception e) {
			handleError(e);
		}
		updateActivityView();
	}
	
	private void unfriend() {
		try {
			SNetControl.unfriend(getSelectedHost());
		} catch (DB461Exception e) {
			handleError(e);
		}
		updateActivityView();
	}
	
	private void contact() {
		try {
			SNetControl.contact(getSelectedHost());
		} catch (Exception e) {
			handleError(e);
		}
		updateActivityView();
	}
	
	private void fixDB() {
		try {
			SNetControl.fixDB();
		} catch (DB461Exception e) {
			handleError(e);
		}
		updateActivityView();
	}
	
	private void dumpDB() {
		Log.d(TAG, SNetControl.dumpDB());
		
		updateActivityView();
	}
	
	private DDNSFullName getSelectedHost() {
		SpinnerHostItem selectedItem = (SpinnerHostItem) spinner.getSelectedItem();
		Log.d(TAG, "getSelectedHost(): Selected " + selectedItem.toString());
		return selectedItem.getName();
	}
	
	private void updateActivityView() {
    	Log.d(TAG, "Updating Activity View");
    	
        try {
            List<SpinnerHostItem> items = new ArrayList<SpinnerHostItem>();
	        List<DDNSFullName> friends = SNetControl.getFriendsList();
	        for (DDNSFullName member : SNetControl.getMembersList()) {
	        	items.add(new SpinnerHostItem(member, friends.contains(member)));
	        }
	        Collections.sort(items);
	        
	        ArrayAdapter<SpinnerHostItem> adapter = new ArrayAdapter<SpinnerHostItem>(this,
	                android.R.layout.simple_spinner_item, items);
	        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	        spinner.setAdapter(adapter);
        } catch (DB461Exception e) {
        	handleError(e);
        }
	}
	
	private void handleError(Exception e) {
		Log.d(TAG, "Encountered Exception: " + e.getMessage());
		for (StackTraceElement ste : e.getStackTrace()) {
			Log.d(TAG, "\t" + ste.toString());
		}
		
    	Toast toast = Toast.makeText(getApplicationContext(), "ERROR: " + e.getMessage(), Toast.LENGTH_SHORT);
    	toast.show();
	}
	
	private static class SpinnerHostItem implements Comparable<SpinnerHostItem> {
		private DDNSFullName host;
		private String value;
		
		private SpinnerHostItem(DDNSFullName host, boolean isFriend) {
			this.host = host;

        	String name = host.getName();
        	if (name.equals(DDNSFullName.ROOT_NAME)) {
        		// Rename to root
        		name = "root";
        	}
        	
            this.value = name;
        	if (isFriend) {
                this.value += " (friend)";
        	}
		}
		
		public DDNSFullName getName() {
			return this.host;
		}
		
		@Override
		public String toString() {
			return this.value;
		}
		
		@Override
		public int compareTo(SpinnerHostItem other) {
			if (this.host.getName().equals(DDNSFullName.ROOT_NAME)) {
				// We are root...so we are less
				return -1;
			} else if (other.host.getName().equals(DDNSFullName.ROOT_NAME)) {
				// They are root...so they are less
				return 1;
			} else {
				// Do a regular comparison of toString values
				return this.value.compareTo(other.value);
			}
		}
	}
}
